- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在编写一个 x86 汇编程序来输出一个十六进制数。该程序是使用 nasm 组装的,图像文件由 qemu 运行。该程序的行为让我很困惑。正如下面的工作程序所建议的那样,我不必将 0x30 添加到数字就可以打印该数字的字符。
; Boot sector code offset: 0x7c00
[org 0x7c00]
mov dx, 0x1fb6 ; The hexadecimal to be printed
call print_hex ; call the function
jmp $ ; jump infinitely
%include "print_string.asm" ; Include the print_string function
print_hex:
pusha ; push all registers to stack
mov ax, 0x4 ; rotate through the number four times
print_hex_loop:
cmp ax, 0x0 ; compare the counter with 0
jle print_hex_end ; if it is zero then jump to the end
mov cx, dx ; move dx to cx
and cx, 0x000F ; take the lower four binary digits of cx
cmp cx, 0xa ;compare the digits with 0xa
jge print_hex_letter ; if it is larger than a, jump to printing character
add cx, 0x0 ; otherwise print the ascii of a number
jmp print_hex_modify_string ; jump to routine for modifing the template
print_hex_letter:
add cx, 0x7 ; print the ascii of a letter
print_hex_modify_string:
mov bx, HEX_OUT ; bring the address of HEX_OUT into dx
add bx, 0x1 ; skip the 0x
add bx, ax ; add the bias
add byte [bx], cl ; move the character into its position
shr dx, 4 ; shift right 4 bits
sub ax, 0x1 ; subtract 1 from the counter
jmp print_hex_loop ; jump back to the start of the function
print_hex_end:
mov bx, HEX_OUT ; move the address of HEX_OUT to bx
call print_string ; call the function print_string
popa ; pop all registers from stack
ret ; return to calling function
HEX_OUT:
db '0x0000',0 ; The template string for printing
times 510-($-$$) db 0 ; fill zeros
dw 0xaa55 ; MAGIC_FLAG for boot
boot_sect.asm
print_string:
pusha
mov ah, 0x0e
mov al, [bx]
print_string_loop:
cmp al, 0x0
je print_string_end
int 0x10
add bx, 0x1
mov al, [bx]
jmp print_string_loop
print_string_end:
popa
ret
打印字符串.asm
该程序的输出符合我的预期,但是当我尝试在数字上添加 0x30 以获取数字的 ASCII 代码时,输出是乱码。是不是有什么技巧,还是我遗漏了一些关键点?
谢谢!
最佳答案
原始问题的答案:
因为你做add byte [bx], cl
将数字写入缓冲区,而缓冲区已经包含'0'
,所以第一次它会正常工作.第二次调用 print_hex
将再次产生乱码,因为 HEX_OUT
内容已经被修改(琐事:第一次打印哪个十六进制数也可以正确打印第二个值? ).
现在只是为了好玩,我添加了我可能如何为自己做print_hex
。也许它会为您的 x86 ASM 编程提供额外的想法,我试图对其进行大量评论以解释我为什么以我正在做的方式做事:
首先我会分离格式化函数,这样我最终可以在别处重用它,所以输入既是数字又是目标缓冲区指针。我使用 LUT(查找表)进行 ASCII 转换,因为代码更简单。如果您关心大小,可以在代码中以更少的字节进行分支并使用较慢的 pusha
/popa
来保存寄存器。
format_hex:
; dx = number, di = 4B output buffer for "%04X" format of number.
push bx ; used as temporary to calculate digits ASCII
push si ; used as pointer to buffer for writing chars
push dx
lea si,[di+4] ; buffer.end() pointer
format_hex_loop:
mov bx,dx ; bx = temporary to extract single digit
dec si ; si = where to write next digit
and bx,0x000F ; separate last digit (needs whole bx for LUT indexing)
shr dx,4 ; shift original number one hex-digit (4 bits) to right
mov bl,[format_hex_ascii_lut+bx] ; convert digit 0-15 value to ASCII
mov [si],bl ; write it into buffer
cmp di,si ; compare buffer.begin() with pointer-to-write
jb format_hex_loop ; loop till first digit was written
pop dx ; restore original values of all modified regs
pop si
pop bx
ret
format_hex_ascii_lut: ; LUT for 0-15 to ASCII conversion
db '0123456789ABCDEF'
然后为了方便起见,也可以添加一个 print_hex
函数,提供它自己的缓冲区以使用“0x”和 nul 终止符进行格式化:
print_hex:
; dx = number to print
push di
push bx
; format the number
mov di,HEX_OUT+2
call format_hex
; print the result to screen
lea bx,[di-2] ; bx = HEX_OUT
; HEX_OUT was already set with "0x" and nul-terminator, otherwise I would do:
; mov word [bx],'0x'
; mov byte [bx+6],0
call print_string
pop bx
pop di
ret
HEX_OUT:
db '0x1234',0 ; The template string for printing
最后是引导代码中的示例用法:
mov dx,0x1fb6 ; The hexadecimal to be printed
call print_hex
mov dx,ax ; works also when called second time
call print_hex ; (but would be nicer to print some space between them)
jmp $ ; loop infinitely
(我确实在一定程度上验证了这段代码(它会编译和运行),尽管只是通过它的不同部分并且在 32b 环境中(修补几行使其成为 32b),所以一些错误可能已经溜进去了。我没有 16b 环境来验证它是否是完整的引导代码。)
关于linux - x86 汇编字符串缓冲区编号到 ASCII,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40671190/
问题故障解决记录 -- Java RMI Connection refused to host: x.x.x.x .... 在学习JavaRMI时,我遇到了以下情况 问题原因:可
我正在玩 Rank-N-type 并尝试输入 x x .但我发现这两个函数可以以相同的方式输入,这很不直观。 f :: (forall a b. a -> b) -> c f x = x x g ::
这个问题已经有答案了: How do you compare two version Strings in Java? (31 个回答) 已关闭 8 年前。 有谁知道如何在Java中比较两个版本字符串
这个问题已经有答案了: How do the post increment (i++) and pre increment (++i) operators work in Java? (14 个回答)
下面是带有 -n 和 -r 选项的 netstat 命令的输出,其中目标字段显示压缩地址 (127.1/16)。我想知道 netstat 命令是否有任何方法或选项可以显示整个目标 IP (127.1.
我知道要证明 : (¬ ∀ x, p x) → (∃ x, ¬ p x) 证明是: theorem : (¬ ∀ x, p x) → (∃ x, ¬ p x) := begin intro n
x * x 如何通过将其存储在“auto 变量”中来更改?我认为它应该仍然是相同的,并且我的测试表明类型、大小和值显然都是相同的。 但即使 x * x == (xx = x * x) 也是错误的。什么
假设,我们这样表达: someIQueryable.Where(x => x.SomeBoolProperty) someIQueryable.Where(x => !x.SomeBoolProper
我有一个字符串 1234X5678 我使用这个正则表达式来匹配模式 .X|..X|X. 我得到了 34X 问题是为什么我没有得到 4X 或 X5? 为什么正则表达式选择执行第二种模式? 最佳答案 这里
我的一个 friend 在面试时遇到了这个问题 找到使该函数返回真值的 x 值 function f(x) { return (x++ !== x) && (x++ === x); } 面试官
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Isn't it easier to work with foo when it is represented b
我是 android 的新手,我一直在练习开发一个针对 2.2 版本的应用程序,我需要帮助了解如何将我的应用程序扩展到其他版本,即 1.x、2.3.x、3 .x 和 4.x.x,以及一些针对屏幕分辨率
为什么案例 1 给我们 :error: TypeError: x is undefined on line... //case 1 var x; x.push(x); console.log(x);
代码优先: # CASE 01 def test1(x): x += x print x l = [100] test1(l) print l CASE01 输出: [100, 100
我正在努力温习我的大计算。如果我有将所有项目移至 'i' 2 个空格右侧的函数,我有一个如下所示的公式: (n -1) + (n - 2) + (n - 3) ... (n - n) 第一次迭代我必须
给定 IP 字符串(如 x.x.x.x/x),我如何或将如何计算 IP 的范围最常见的情况可能是 198.162.1.1/24但可以是任何东西,因为法律允许的任何东西。 我要带198.162.1.1/
在我作为初学者努力编写干净的 Javascript 代码时,我最近阅读了 this article当我偶然发现这一段时,关于 JavaScript 中的命名空间: The code at the ve
我正在编写一个脚本,我希望避免污染 DOM 的其余部分,它将是一个用于收集一些基本访问者分析数据的第 3 方脚本。 我通常使用以下内容创建一个伪“命名空间”: var x = x || {}; 我正在
我尝试运行我的test_container_services.py套件,但遇到了以下问题: docker.errors.APIError:500服务器错误:内部服务器错误(“ b'{” message
是否存在这两个 if 语句会产生不同结果的情况? if(x as X != null) { // Do something } if(x is X) { // Do something } 编
我是一名优秀的程序员,十分优秀!