どのようにしてtasmに負の数値を印刷できますか?誰か助けてください。 例:減算を行う場合2-7 =( - 5)。 -5をどのように印刷できますか?TASMの負の数値を表示
0
A
答えて
0
自分で番号変換を行う必要があります(独自の機能など)。私はこのTASM5互換Win32アプリを例として一緒に投げましたが、数え切れないほどの数の文字列変換サンプルをオンラインで見つけることができると確信しています。
このような単純な目的のためのコードのように思えるかもしれませんが、インクルードファイルやライブラリの任意の数のプログラムで使用できるように十分に汎用的に設計された "共通の"関数を配置すると、下部のappMain()関数はわずか約10行のコードです。私は完全な実例であるためにすべてを1つのファイルに投げました。
以下に示すnumToString()関数は、DWORDを関数に渡されるバッファ内の数値に変換します。コードの残りの部分は、いくつかの一般的なWriteConsoleラッパーと共に関数を呼び出すためのフレームワークに過ぎません。 numToString()は、数値を任意のベース(16進数や2進数など)に変換することをサポートしています。この例では、negative-flagを有効にしてbase-10を指定する引数を渡します(DWORD番号を符号付きとして扱うことを示します)。
次のようにnumToString()アルゴリズムは次のとおりです。
-If number is to be interpreted as signed and IS negative, convert it to positive and set bHasSign flag
-Repeatedly divide positive (in loop) number by base (radix) and convert remainder to ASCII char; this gives us each digit of the resulting string starting with the least significant digit
-Append negative "-" to end based on bHasSign flag
-NULL terminate destination buffer
-Because the algorithm actually computes digits from least significant to most significant, we need to reverse the resultant string (including negative sign) before returning. In English, we read digits starting with most significant first.
The reverse algorithm swaps the outer bytes, then the next inner bytes, and so on until it reaches the middle of the string. This swapping allows us to avoid setting up a temporary buffer for the character reversal.
プログラム出力:
The number is: -352
プログラムリスト:の
.386
.model flat
GetStdHandle PROTO STDCALL :DWORD
WriteConsoleA PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
ExitProcess PROTO STDCALL :DWORD
getStringLength PROTO STDCALL :DWORD
outputString PROTO STDCALL :DWORD, :DWORD
numToString PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
NULL equ 0
STD_OUTPUT_HANDLE equ -11
MAXLEN_BINARYNUM_BUFFER equ 33 ;max string length for number->string buffer assuming smallest base (32 bits) + NULL accounts for largest possible binary number
MAXLEN_BINARYNUM_BUFFER_AS_DWORD equ 9 ;36-byte hack for MAXLEN_BINARYNUM_BUFFER used below so TASM doesn't mess up Win32 stack alignment
CODE_ERROR_BUFLEN equ -10
.data
szMsg db 'The number is: ',0
.code
;
; getStringLength() - returns zero terminated string length in eax
;
getStringLength PROC STDCALL pszString:DWORD
;count the characters in the string and store result in ecx
lea esi,pszString ;make esi point to first character in string
mov esi,[esi]
mov edi,esi ;edi pointer to first character also
cld
@@countloop:
lodsb
cmp al,0
jne SHORT @@countloop
dec esi ;we're now pointing past NULL, so back up one
sub esi,edi ;subtract beginning pointer from pointer at NULL so that esi now contains string count
;return string length in returned in eax
mov eax,esi
ret
getStringLength ENDP
;
; outputString(pszString) - outputs a zero terminated string
; returns 0 on failure or final character count upon success (excluding NULL terminator)
;
outputString PROC STDCALL
LOCALS
ARG hConsole:DWORD
ARG pszString:DWORD
LOCAL dwCharsWrote:DWORD
;get string length (in eax)
lea esi,pszString
mov esi,[esi]
call getStringLength ,esi
;load string pointer into esi
lea esi,pszString
mov esi,[esi]
;load dwCharsWrote pointer into edx
lea edx,dwCharsWrote
;write string to console
call WriteConsoleA ,hConsole,edi,eax,edx,NULL
;if the function fails, return 0, otherwise return the characters written
cmp eax,0
jz @@funcdone
mov eax,[dwCharsWrote]
@@funcdone:
ret
outputString ENDP ;outputString()
;
; numToString() - converts unsigned DWORD to digit string
;
numToString PROC STDCALL
ARG uNum:DWORD
ARG uBase:DWORD
ARG pDest:DWORD
ARG uDestLen:DWORD
ARG bSigned:DWORD
LOCAL pEnd:DWORD
LOCAL bHasSign:DWORD
;default to number not signed
mov [bHasSign],0
;if we're interpreting number as signed, see if 32nd bit (sign flag) is set
cmp bSigned,0
jz SHORT @@setup_div_loop
test DWORD PTR [uNum],080000000h
jz SHORT @@setup_div_loop
mov [bHasSign],1 ;number is signed: set sign flag, then remove the sign
not [uNum] ; from the bits VIA: bitwise NOT, then adding 1
inc [uNum] ; this will give us an unsigned representation of the same number
; for which we will add a negative sign character at end
;setup divide/remainder loop
@@setup_div_loop:
mov edi,[pDest] ;edi points to beginning of dest buffer
mov ebx,edi ;pEnd variable will point 1 past end of buffer
add ebx,[uDestLen]
mov [pEnd],ebx
mov ebx,[uBase] ;ebx will hold the base to convert to
mov eax,uNum ;eax is our number to convert
@@divloop:
;range check buffer
cmp edi,[pEnd] ;if we are we outside of buffer?
jae SHORT @@errorbufoverflow ; we've overflowed
;setup 32-bit divide - divide eax by radix (ebx)
xor edx,edx
div ebx
;assume remainder can always fit in byte (should range check radix)
; and convert value to ASCII (values past 9 get hex digits
cmp dl,9
ja SHORT @@convletters
add dl,48 ;convert 0-9 to ASCII digits
jmp SHORT @@chardone
@@convletters:
add dl,55 ;convert A-F (letter A starts at 65, and we want to back it up by 10 to 55 such that 65 is for the value 10)
@@chardone:
mov BYTE PTR [edi],dl ;remainder goes in buffer
inc edi ;point at next character
cmp eax,0 ;if quotient nonzero, keep dividing
jnz SHORT @@divloop
;
; loop above complete
;
;do we need to add sign?
cmp [bHasSign],0
jz SHORT @@nullTerminate
; yes, range check that we have room
cmp edi,[pEnd]
jae SHORT @@errorbufoverflow
; we have room, add sign character to string
mov BYTE PTR [edi],'-'
inc edi
@@nullTerminate:
;range check buffer that we can NULL terminate the string
cmp edi,[pEnd]
jae SHORT @@errorbufoverflow
mov BYTE PTR [edi],0 ;SUCCESS - NULL terminate
;return character count in eax (not counting null)
mov eax,edi ;subtract start of buffer
sub eax,[pDest] ; from ending position of buffer to obtain count
;
; we now have correct numeric string, but with least significant digits first
; we must reverse the string to make it human-readible
;
mov esi,[pDest] ;esi is left pointer
dec edi ;edi is right pointer
@@reverseloop:
cmp esi,edi
jae SHORT @@procdone ;if esi ever meets or goes past edi, we're done!
mov dl,BYTE PTR [esi] ;swap esi and edi bytes
xchg dl,BYTE PTR [edi]
mov BYTE PTR [esi],dl
dec edi
inc esi
jmp SHORT @@reverseloop
@@errorbufoverflow:
;ERROR: buffer length too small
mov eax,CODE_ERROR_BUFLEN
@@procdone:
ret
numToString ENDP
;
; appMain()
;
appMain PROC STDCALL
LOCAL hConsole:DWORD
LOCAL szCode[MAXLEN_BINARYNUM_BUFFER_AS_DWORD]:DWORD
;get handle to console
call GetStdHandle ,STD_OUTPUT_HANDLE
mov hConsole,eax
;output message
call outputString ,hConsole,OFFSET szMsg
;this is your negative value
mov eax,-352
;convert value to string
lea esi,[szCode]
call numToString ,eax,10,esi,MAXLEN_BINARYNUM_BUFFER,1
;output number buffer
lea esi,[szCode]
call outputString ,hConsole,esi
ret
appMain ENDP
;
; Program Entry Point
;
_start:
call appMain
call ExitProcess ,eax
end _start
関連する問題
- 1. Phoenixが負の整数値を正しく表示しない
- 2. 負の通貨の表示
- 3. jQueryフォーマットの負の数値
- 4. SOLRクエリの負の数値
- 5. Google ChartはyAxisに負の値を表示し続ける
- 6. Focus + Context via Brushingは負の値を表示できません
- 7. TASMのパラメータを持つ関数
- 8. 負の値を持つ小数のkeypressの正規表現
- 9. 負の数のビット表現
- 10. 関数の値を表示
- 11. Kadaneアルゴリズム負の数値
- 12. base_convertと負の数値
- 13. MIPSの減算結果として負の数を表示
- 14. Tasmで文字列を数値に変換するには?
- 15. Python Lamba関数の負の数値
- 16. 数字の和(INC。負の数値)
- 17. C#:パーセント値が負の値であるかどうかを表示
- 18. Visual Studio負荷テスト - データソース値をテスト詳細に表示
- 19. C#数値のリストを負の数値に変換する
- 20. 正規表現の10進数式。負の値から正の値
- 21. Googleスプレッドシート - 数式に負の時間が表示されない
- 22. 係数を負の値にする
- 23. FancyVideoライトボックス - ページの表示負荷
- 24. jQueryツールツールヒント:ページの負荷に表示
- 25. Pythonでの負の数値の分割
- 26. Google Visualization API:折れ線グラフ - Y軸の負の値を非表示にする
- 27. アドレスの計算:ポインタ+非負の数値
- 28. 整数計画モデルの負の値
- 29. コンパイラと負の数の表現
- 30. カールクッキージャー負の値
可能性のある重複した[として負の数値を使用する方法アセンブリの1つ?](http://stackoverflow.com/questions/14817184/how-to-use-negative-numbers-as-one-in-assembly) – JJJ